/// <reference name="MicrosoftAjax.debug.js" />
/// <reference path="../ExtenderDuplicator.debug.js" />

Type.registerNamespace("BM");

// AutoCompleteValueHandler object

BM.AutoCompleteValueHandler = function(leafItem) {
    BM.AutoCompleteValueHandler.initializeBase(this, [leafItem]);
    this.knownToBeValid = new Object();    
}

BM.AutoCompleteValueHandler.prototype = {
    load: function() {
        BM.AutoCompleteValueHandler.callBaseMethod(this, 'load');
        if (this.leafItem.getMode() != MItem.EditMode) {
            return;
        }
        
        var extender = this.createOrGetExtender();
        if (this.acceptResponsesOnly()) {

            extender.add_itemSelected(Function.createDelegate(this, this.raiseItemSelected));
            extender.add_hiding(Function.createDelegate(this, this.onHiding));
            if (this.getValue() != '') {
                this.knownToBeValid[this.getValue()] = this.getControlValue();
            }
        }
    },

    acceptResponsesOnly: function() {
        return this.getHiddenInput() != null;
    },

    onchange: function(handler) {
        /// <summary>
        /// fire the onchange event when no items are selected in the extender        
        /// </summary>
        if (!this.acceptResponsesOnly()) {
            BM.AutoCompleteValueHandler.callBaseMethod(this, 'onchange', [handler]);
            return;
        }
        if (this.getExtender()._selectIndex == -1) {
            this.setValue(this.getControlValue());
        }
    },

    getHiddenInput: function() {
        /// <returns domElement="true" >
        /// the hidden input for keeping the data
        /// </returns>
        return $(this.getLeafNode()).children('.HiddenInput')[0];

    },

    unload: function() {
        this.getExtender().dispose();
    },

    raiseItemSelected: function(event, args) {
        /// <summary>
        /// set text and value on item selected
        /// </summary>
        this.setTextAndValue(args._text, args._value);
    },

    setTextAndValue: function(text, value) {
        /// <summary>
        /// change the value only if it is different than before
        /// </summary>
        this.setControlValue(text);
        if (value == this.getValue()) {
            return;
        }
        if (value != null) {
            this.knownToBeValid[value] = text;
        }
        this.getHiddenInput().value = value;
        this.leafItem.raiseChanged();
    },

    setEditModeValue: function(value) {
        /// <summary>
        /// if the value is currently set and it matches the key, do not do anything
        /// fire the autocomplete timer tick method to invoke the webservice
        /// </summary>
        if (!this.acceptResponsesOnly()) {
            BM.AutoCompleteValueHandler.callBaseMethod(this, 'setEditModeValue', [value]);
            return;
        }
        if (this.getValue() && this.knownToBeValid[this.getValue()] == value) {
            return;
        }
        this.setControlValue(value);
        this.getExtender()._onTimerTick();
    },

    getEditModeValue: function() {
        if (!this.acceptResponsesOnly()) {
            return BM.AutoCompleteValueHandler.callBaseMethod(this, 'getEditModeValue');
        }
        return this.getHiddenInput().value;
    },

    setCompletionItem: function(completionItem) {
        try {
            var pair = Sys.Serialization.JavaScriptSerializer.deserialize('(' + completionItem + ')');
            if (pair && pair.First) {
                // Use the text and value pair returned from the web service
                this.setTextAndValue(pair.First, pair.Second);
            } else {
                // If the web service only returned a regular string, use it for
                // both the text and the value
                this.setTextAndValue(pair, pair);
            }
        } catch (ex) {
            this.setTextAndValue(completionItem, completionItem);
        }
    },

    onHiding: function(sender, args) {
        /// <summary>
        /// Collect the webservice response from 'setEditModeValue' method
        /// </summary>
        if ((!sender._textBoxHasFocus) || (this.getControlValue() != sender._currentCompletionWord())) {
            if (this.getValue() && this.knownToBeValid[this.getValue()] == this.getControlValue()) {
                return;
            }

            var items;
            if (sender._cache) {
                items = sender._cache[this.getControlValue()];
            }

            if (items && items.length > 0) {
                this.setCompletionItem(items[0]);
            } else {
                this.setTextAndValue(this.getControlValue(), '');
            }
        }
    },

    createOrGetExtender: function() {
        var extender = this.getExtender();
        if (extender == null) {
            extender = this.createExtender();
        }
        return extender;
    },

    getExtender: function() {
        return $find(this.getValueHandlerId() + "_AC");
    },

    getValueHandlerId: function() {
        return this.leafItem.node.id + "_VH";
    },

    getPrototypeId: function() {
        return this.leafItem.basis.node.id + "_VH";
    },

    createExtender: function() {
        BM.ExtenderDuplicator.run(this.getPrototypeId(), this.getValueHandlerId());
        return this.getExtender();
    }
}

BM.ValueHandler['AutoCompleteValueHandler'] = BM.AutoCompleteValueHandler;
BM.AutoCompleteValueHandler.registerClass("BM.AutoCompleteValueHandler", BM.TextBoxValueHandler);

